#ifndef TEXTUREMANAGER_H
#define TEXTUREMANAGER_H

#pragma once

#include "../ToolkitLayer.h"
#include <vector>

/**
 * This class manages a set of textures loaded from image files. It holds a
 * list of OpenGL texture names that can be used for loading and applying the
 * textures.
 *
 * @author Fabricio Anastacio - fabriciocfa@yahoo.com
 * @since August 7, 2007
 */
class TOOLKITLAYER_API TextureManager
{
	// Attributes
private:
	/** List of OpenGL texture names available. */
	std::vector<unsigned int> textureNames;
	/** Flag that determines if mipmapping should be used. */
	bool mipMapping;
	/** Flag that determines if linear filtering should be used. */
	bool linearFiltering;
	/** Flag that determines if texture compression should be used. */
	bool texCompression;
	/** Flag that determines if ARB texture compression should be used. */
	bool texCompressionARB;
	/** The OpenGL texture format to be used. */
	unsigned int texFormatGL;

	// HARDWARE TEXTURE SUPPORT
	/** Support to S3TC texture compression. */
	bool supportGL_EXT_texture_compression_s3tc;
	/** Support to ARB texture compression. */
	bool supportGL_ARB_texture_compression;


	// Methods
public:
	/**
	 * Constructs a texture manager.
	 */
	TextureManager(void);
	/**
	 * Destroys this texture manager.
	 */
	~TextureManager(void);

	/**
	 * Loads as texture the given image file.
	 *
	 * @param imageFile the path to the image file to be loaded.
	 */
	void loadTexture(const char* imageFile);
	/**
	 * Loads as textures the given image files.
	 *
	 * @param imageFiles the list of the paths to the image files to be loaded.
	 */
	void loadTextures(std::vector<std::string> imageFiles);

	/**
	 * Returns a texture name randomly chosen from the ones currently in the
	 * list.
	 *
	 * @return a texture name randomly chosen from the ones currently in the
	 * list.
	 */
	unsigned int getRandomTextureName();

	
	// ACCESSOR METHODS
	/**
	 * Returns the list of texture names available.
	 *
	 * @return the list of texture names available.
	 */
	std::vector<unsigned int> getTextureNames();
	/**
	 * Returns the texture name in the given index postion in the list.
	 *
	 * @return the texture name in the given index postion in the list.
	 */
	unsigned int getTextureName(unsigned int index);
	/**
	 * Returns true if mip-mapping is set when loading textures.
	 *
	 * @return true if mip-mapping is set when loading textures, false
	 * otherwise.
	 */
	bool isMipMapping();
	/**
	 * Sets the use of mip-mapping.
	 *
	 * @param value if true mip-mapping is used when loading textures.
	 */
	void setMipMapping(bool value);
	/**
	 * Returns true if linear filtering is set when loading textures.
	 *
	 * @return true if linear filtering is set when loading textures, false
	 * otherwise.
	 */
	bool isLinearFiltering();
	/**
	 * Sets the use of linear filtering.
	 *
	 * @param value if true linear filtering is used when loading textures.
	 */
	void setLinearFiltering(bool value);
	/**
	 * Returns true if texture compression is set when loading textures.
	 *
	 * @return true if texture compression is set when loading textures, false
	 * otherwise.
	 */
	bool isTexCompression();
	/**
	 * Sets the use of texture compression.
	 *
	 * @param value if true texture compression is used when loading textures.
	 */
	void setTexCompression(bool value);
	/**
	 * Returns true if ARB texture compression is set when loading textures.
	 *
	 * @return true if ARB texture compression is set when loading textures,
	 * false otherwise.
	 */
	bool isTexCompressionARB();
	/**
	 * Sets the use of ARB texture compression.
	 *
	 * @param value if true ARB texture compression is used when loading textures.
	 */
	void setTexCompressionARB(bool value);

private:
	/**
	 * Checks for hardware texture compression support and sets the proper
	 * flags.
	 */
	void checkHWSupport();
	/**
	 * Sets the texture parameters based on the current manager option flags.
	 */
	void setTextureParameters();
	/**
	 * Sets the texture parameters based on the current manager option flags.
	 *
	 * @param hasAlpha determines if the texture format to be set should
	 * consider an alpha channel.
	 */
	void setTextureFormat(bool hasAlpha);
};

#endif // TEXTUREMANAGER_H
